home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / umoria / generate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-07-28  |  26.2 KB  |  1,060 lines

  1. #include "constants.h"
  2. #include "config.h"
  3. #include "types.h"
  4. #include "externs.h"
  5.  
  6. typedef struct coords {
  7.   int x, y;
  8. } coords;
  9.  
  10. coords doorstk[100];
  11. int doorptr;
  12.  
  13.  
  14. /* Always picks a correct direction        */
  15. correct_dir(rdir, cdir, y1, x1, y2, x2)
  16. int *rdir, *cdir;
  17. register int y1, x1, y2, x2;
  18. {
  19.   if (y1 < y2)
  20.     *rdir =  1;
  21.   else if (y1 == y2)
  22.     *rdir =  0;
  23.   else
  24.     *rdir = -1;
  25.   if (x1 < x2)
  26.     *cdir =  1;
  27.   else if (x1 == x2)
  28.     *cdir =  0;
  29.   else
  30.     *cdir = -1;
  31.   if ((*rdir != 0) && (*cdir != 0))
  32.     switch(randint(2))
  33.       {
  34.       case 1:
  35.     *rdir = 0;
  36.     break;
  37.       case 2:
  38.     *cdir = 0;
  39.     break;
  40.       }
  41. }
  42.  
  43.  
  44. /* Chance of wandering direction            */
  45. rand_dir(rdir, cdir, y1, x1, y2, x2, chance)
  46. int *rdir, *cdir;
  47. int y1, x1, y2, x2;
  48. int chance;
  49. {
  50.   switch(randint(chance))
  51.     {
  52.     case 1:
  53.       *rdir = -1;
  54.       *cdir =  0;
  55.       break;
  56.     case 2:
  57.       *rdir =  1;
  58.       *cdir =  0;
  59.       break;
  60.     case 3:
  61.       *rdir =  0;
  62.       *cdir = -1;
  63.       break;
  64.     case 4:
  65.       *rdir =  0;
  66.       *cdir =  1;
  67.       break;
  68.     default:
  69.       correct_dir(rdir, cdir, y1, x1, y2, x2);
  70.       break;
  71.     }
  72. }
  73.  
  74.  
  75. /* Blanks out entire cave                -RAK-    */
  76. blank_cave()
  77. {
  78.   register int i, j;
  79.   register cave_type *c_ptr;
  80.  
  81.   c_ptr = &cave[0][0];
  82.   for (i = 0; i < MAX_HEIGHT; i++)
  83.     for (j = 0; j < MAX_WIDTH; j++)
  84.       *c_ptr++ = blank_floor;
  85. }
  86.  
  87.  
  88. /* Fills in empty spots with desired rock        -RAK-    */
  89. /* Note: 9 is a temporary value.                */
  90. fill_cave(fill)
  91. floor_type fill;
  92. {
  93.   register int i, j;
  94.   register cave_type *c_ptr;
  95.  
  96.   for (i = 1; i < cur_height-1; i++)
  97.     for (j = 1; j < cur_width-1; j++)
  98.       {
  99.     c_ptr = &cave[i][j];
  100.     if ((c_ptr->fval == 0) || (c_ptr->fval == 8) || (c_ptr->fval == 9))
  101.       {
  102.         c_ptr->fval = fill.ftval;
  103.         c_ptr->fopen = fill.ftopen;
  104.       }
  105.       }
  106. }
  107.  
  108.  
  109. /* Places indestructible rock around edges of dungeon    -RAK-    */
  110. place_boundary()
  111. {
  112.   register int i;
  113.  
  114.   for (i = 0; i < cur_height; i++)
  115.     {
  116.       cave[i][0].fval            = boundary_wall.ftval;
  117.       cave[i][0].fopen           = boundary_wall.ftopen;
  118.       cave[i][cur_width-1].fval  = boundary_wall.ftval;
  119.       cave[i][cur_width-1].fopen = boundary_wall.ftopen;
  120.     }
  121.   for (i = 0; i < cur_width; i++)
  122.     {
  123.       cave[0][i].fval             = boundary_wall.ftval;
  124.       cave[0][i].fopen            = boundary_wall.ftopen;
  125.       cave[cur_height-1][i].fval  = boundary_wall.ftval;
  126.       cave[cur_height-1][i].fopen = boundary_wall.ftopen;
  127.     }
  128. }
  129.  
  130.  
  131. /* Places "streamers" of rock through dungeon        -RAK-    */
  132. place_streamer(rock, treas_chance)
  133. floor_type rock;
  134. int treas_chance;
  135. {
  136.   register int i, tx, ty;
  137.   int y, x, dir, t1, t2;
  138.   int flag;
  139.   register cave_type *c_ptr;
  140.  
  141.   /* Choose starting point and direction        */
  142.   y = (cur_height/2.0) + 11 - randint(23);
  143.   x = (cur_width/2.0)  + 16 - randint(33);
  144.  
  145.   dir = randint(8);    /* Number 1-4, 6-9    */
  146.   if (dir > 4)
  147.     dir = dir + 1;
  148.  
  149.   /* Place streamer into dungeon            */
  150.   flag = FALSE;    /* Set to true when y, x are out-of-bounds*/
  151.   t1 = 2*DUN_STR_RNG + 1;    /* Constants    */
  152.   t2 =   DUN_STR_RNG + 1;
  153.   do
  154.     {
  155.       for (i = 0; i < DUN_STR_DEN; i++)
  156.     {
  157.       ty = y + randint(t1) - t2;
  158.       tx = x + randint(t1) - t2;
  159.       if (in_bounds(ty, tx))
  160.         {
  161.           c_ptr = &cave[ty][tx];
  162.           if (c_ptr->fval == rock_wall1.ftval)
  163.         {
  164.           c_ptr->fval = rock.ftval;
  165.           c_ptr->fopen = rock.ftopen;
  166.           if (randint(treas_chance) == 1)
  167.             place_gold(ty, tx);
  168.         }
  169.         }
  170.     }
  171.       if (!move(dir, &y, &x))
  172.     flag = TRUE;
  173.     }
  174.   while (!flag);
  175. }
  176.  
  177.  
  178. /* Place a trap with a given displacement of point    -RAK-    */
  179. vault_trap(y, x, yd, xd, num)
  180. int y, x, yd, xd, num;
  181. {
  182.   register int count, y1, x1;
  183.   int i, flag;
  184.   register cave_type *c_ptr;
  185.  
  186.   for (i = 0; i < num; i++)
  187.     {
  188.       flag = FALSE;
  189.       count = 0;
  190.       do
  191.     {
  192.       y1 = y - yd - 1 + randint(2*yd+1);
  193.       x1 = x - xd - 1 + randint(2*xd+1);
  194.       c_ptr = &cave[y1][x1];
  195.       if ((c_ptr->fval > 0) && (c_ptr->fval < 8) && (c_ptr->fval != 3))
  196.         if (c_ptr->tptr == 0)
  197.           {
  198.         place_trap(y1, x1, 1, randint(MAX_TRAPA)-1);
  199.         flag = TRUE;
  200.           }
  201.       count++;
  202.     }
  203.       while ((!flag) && (count <= 5));
  204.     }
  205. }
  206.  
  207.  
  208. /* Place a trap with a given displacement of point    -RAK-    */
  209. vault_monster(y, x, num)
  210. int y, x, num;
  211. {
  212.   register int i;
  213.   int y1, x1;
  214.  
  215.   for (i = 0; i < num; i++)
  216.     {
  217.       y1 = y;
  218.       x1 = x;
  219.       (void) summon_monster(&y1, &x1, TRUE);
  220.     }
  221. }
  222.  
  223.  
  224. /* Builds a room at a row, column coordinate        -RAK-    */
  225. build_room(yval, xval)
  226. int yval, xval;
  227. {
  228.   register int i, j;
  229.   register int y_height, y_depth;
  230.   register int x_left, x_right;
  231.   floor_type cur_floor;
  232.  
  233.   if (dun_level <= randint(25))
  234.     cur_floor = lopen_floor;    /* Floor with light    */
  235.   else
  236.     cur_floor = dopen_floor;    /* Dark floor        */
  237.   y_height = yval - randint(4);
  238.   y_depth  = yval + randint(3);
  239.   x_left   = xval - randint(11);
  240.   x_right  = xval + randint(11);
  241.   for (i = y_height; i <= y_depth; i++)
  242.     for (j = x_left; j <= x_right; j++)
  243.       {
  244.     cave[i][j].fval  = cur_floor.ftval;
  245.     cave[i][j].fopen = cur_floor.ftopen;
  246.       }
  247.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  248.     {
  249.       cave[i][x_left-1].fval   = rock_wall1.ftval;
  250.       cave[i][x_left-1].fopen  = rock_wall1.ftopen;
  251.       cave[i][x_right+1].fval  = rock_wall1.ftval;
  252.       cave[i][x_right+1].fopen = rock_wall1.ftopen;
  253.     }
  254.   for (i = x_left; i <= x_right; i++)
  255.     {
  256.       cave[y_height-1][i].fval  = rock_wall1.ftval;
  257.       cave[y_height-1][i].fopen = rock_wall1.ftopen;
  258.       cave[y_depth+1][i].fval   = rock_wall1.ftval;
  259.       cave[y_depth+1][i].fopen  = rock_wall1.ftopen;
  260.     }
  261. }
  262.  
  263.  
  264. /* Builds a room at a row, column coordinate        -RAK-    */
  265. /* Type 1 unusual rooms are several overlapping rectangular ones    */
  266. build_type1(yval, xval)
  267. int yval, xval;
  268. {
  269.   int y_height, y_depth;
  270.   int x_left, x_right;
  271.   register int i0, i, j;
  272.   floor_type cur_floor;
  273.   register cave_type *c_ptr;
  274.  
  275.   if (dun_level <= randint(25))
  276.     cur_floor = lopen_floor;    /* Floor with light    */
  277.   else
  278.     cur_floor = dopen_floor;    /* Dark floor        */
  279.   for (i0 = 0; i0 < (1 + randint(2)); i0++)
  280.     {
  281.       y_height = yval - randint(4);
  282.       y_depth  = yval + randint(3);
  283.       x_left   = xval - randint(11);
  284.       x_right  = xval + randint(11);
  285.       for (i = y_height; i <= y_depth; i++)
  286.     for (j = x_left; j <= x_right; j++)
  287.       {
  288.         cave[i][j].fval  = cur_floor.ftval;
  289.         cave[i][j].fopen = cur_floor.ftopen;
  290.       }
  291.       for (i = (y_height - 1); i <= (y_depth + 1); i++)
  292.     {
  293.       c_ptr = &cave[i][x_left-1];
  294.       if (c_ptr->fval != cur_floor.ftval)
  295.         {
  296.           c_ptr->fval  = rock_wall1.ftval;
  297.           c_ptr->fopen = rock_wall1.ftopen;
  298.         }
  299.       c_ptr = &cave[i][x_right+1];
  300.         if (c_ptr->fval != cur_floor.ftval)
  301.           {
  302.         c_ptr->fval  = rock_wall1.ftval;
  303.         c_ptr->fopen = rock_wall1.ftopen;
  304.           }
  305.     }
  306.       for (i = x_left; i <= x_right; i++)
  307.     {
  308.       c_ptr = &cave[y_height-1][i];
  309.       if (c_ptr->fval != cur_floor.ftval)
  310.         {
  311.           c_ptr->fval  = rock_wall1.ftval;
  312.           c_ptr->fopen = rock_wall1.ftopen;
  313.         }
  314.       c_ptr = &cave[y_depth+1][i];
  315.         if (c_ptr->fval != cur_floor.ftval)
  316.           {
  317.         c_ptr->fval  = rock_wall1.ftval;
  318.         c_ptr->fopen = rock_wall1.ftopen;
  319.           }
  320.     }
  321.     }
  322. }
  323.  
  324.  
  325. /* Builds an unusual room at a row, column coordinate    -RAK-    */
  326. /* Type 2 unusual rooms all have an inner room:            */
  327. /*   1 - Just an inner room with one door            */
  328. /*   2 - An inner room within an inner room            */
  329. /*   3 - An inner room with pillar(s)                */
  330. /*   4 - Inner room has a maze                    */
  331. /*   5 - A set of four inner rooms                */
  332. build_type2(yval, xval)
  333. int yval, xval;
  334. {
  335.   register int i, j;
  336.   register int y_height, y_depth;
  337.   register int x_left, x_right;
  338.   floor_type cur_floor;
  339.  
  340.   if (dun_level <= randint(30))
  341.     cur_floor = lopen_floor;    /* Floor with light    */
  342.   else
  343.     cur_floor = dopen_floor;    /* Dark floor        */
  344.   y_height = yval - 4;
  345.   y_depth  = yval + 4;
  346.   x_left   = xval - 11;
  347.   x_right  = xval + 11;
  348.   for (i = y_height; i <= y_depth; i++)
  349.     for (j = x_left; j <= x_right; j++)
  350.       {
  351.     cave[i][j].fval  = cur_floor.ftval;
  352.     cave[i][j].fopen = cur_floor.ftopen;
  353.       }
  354.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  355.     {
  356.       cave[i][x_left-1].fval   = rock_wall1.ftval;
  357.       cave[i][x_left-1].fopen  = rock_wall1.ftopen;
  358.       cave[i][x_right+1].fval  = rock_wall1.ftval;
  359.       cave[i][x_right+1].fopen = rock_wall1.ftopen;
  360.     }
  361.   for (i = x_left; i <= x_right; i++)
  362.     {
  363.       cave[y_height-1][i].fval  = rock_wall1.ftval;
  364.       cave[y_height-1][i].fopen = rock_wall1.ftopen;
  365.       cave[y_depth+1][i].fval   = rock_wall1.ftval;
  366.       cave[y_depth+1][i].fopen  = rock_wall1.ftopen;
  367.     }
  368.   /* The inner room        */
  369.   y_height = y_height + 2;
  370.   y_depth  = y_depth  - 2;
  371.   x_left   = x_left   + 2;
  372.   x_right  = x_right  - 2;
  373.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  374.     {
  375.       cave[i][x_left-1].fval   = 8;
  376.       cave[i][x_right+1].fval  = 8;
  377.     }
  378.   for (i = x_left; i <= x_right; i++)
  379.     {
  380.       cave[y_height-1][i].fval  = 8;
  381.       cave[y_depth+1][i].fval   = 8;
  382.     }
  383.   /* Inner room variations        */
  384.   switch(randint(5))
  385.     {
  386.     case 1:    /* Just an inner room...    */
  387.       switch(randint(4))     /* Place a door    */
  388.     {
  389.     case 1:    place_secret_door(y_height-1, xval); break;
  390.     case 2:    place_secret_door(y_depth+1, xval); break;
  391.     case 3:    place_secret_door(yval, x_left-1); break;
  392.     case 4:    place_secret_door(yval, x_right+1); break;
  393.     }
  394.       vault_monster(yval, xval, 1);
  395.       break;
  396.     case 2:    /* Treasure Vault    */
  397.       switch(randint(4))    /* Place a door    */
  398.     {
  399.     case 1:    place_secret_door(y_height-1, xval); break;
  400.     case 2:    place_secret_door(y_depth+1, xval); break;
  401.     case 3:    place_secret_door(yval, x_left-1); break;
  402.     case 4:    place_secret_door(yval, x_right+1); break;
  403.     }
  404.       for (i = yval-1; i <= yval+1; i++)
  405.     {
  406.       cave[i][xval-1].fval   = 8;
  407.       cave[i][xval+1].fval   = 8;
  408.     }
  409.       cave[yval-1][xval].fval  = 8;
  410.       cave[yval+1][xval].fval  = 8;
  411.       switch(randint(4))    /* Place a door    */
  412.     {
  413.     case 1:    place_locked_door(yval-1, xval); break;
  414.     case 2:    place_locked_door(yval+1, xval); break;
  415.     case 3:    place_locked_door(yval, xval-1); break;
  416.     case 4:    place_locked_door(yval, xval+1); break;
  417.     }
  418.       /* Place an object in the treasure vault    */
  419.       switch(randint(10))
  420.     {
  421.     case 1: place_up_stairs(yval, xval); break;
  422.     case 2: place_down_stairs(yval, xval); break;
  423.     default: place_object(yval, xval); break;
  424.     }
  425.       /* Guard the treasure well        */
  426.       vault_monster(yval, xval, 2+randint(3));
  427.       /* If the monsters don't get 'em...    */
  428.       vault_trap(yval, xval, 4, 10, 2+randint(3));
  429.       break;
  430.     case 3:    /* Inner pillar(s)...    */
  431.       switch(randint(4))  /* Place a door    */
  432.     {
  433.     case 1:    place_secret_door(y_height-1, xval); break;
  434.     case 2:    place_secret_door(y_depth+1, xval); break;
  435.     case 3:    place_secret_door(yval, x_left-1); break;
  436.     case 4:    place_secret_door(yval, x_right+1); break;
  437.     }
  438.       for (i = yval-1; i <= yval+1; i++)
  439.     for (j = xval-1; j <= xval+1; j++)
  440.       cave[i][j].fval   = 8;
  441.       if (randint(2) == 1)
  442.     {
  443.       switch(randint(2))
  444.         {
  445.         case 1:
  446.           for (i = yval-1; i <= yval+1; i++)
  447.         for (j = xval-6; j <= xval-4; j++)
  448.           cave[i][j].fval   = 8;
  449.           for (i = yval-1; i <= yval+1; i++)
  450.         for (j = xval+4; j <= xval+6; j++)
  451.           cave[i][j].fval   = 8;
  452.           break;
  453.         case 2:
  454.           for (i = yval-1; i <= yval+1; i++)
  455.         for (j = xval-7; j <= xval-5; j++)
  456.           cave[i][j].fval   = 8;
  457.           for (i = yval-1; i <= yval+1; i++)
  458.         for (j = xval+5; j <= xval+7; j++)
  459.           cave[i][j].fval   = 8;
  460.           break;
  461.         }
  462.     }
  463.       if (randint(3) == 1)     /* Inner rooms    */
  464.     {
  465.       for (i = xval-5; i <= xval+5; i++)
  466.         {
  467.           cave[yval-1][i].fval = 8;
  468.           cave[yval+1][i].fval = 8;
  469.         }
  470.       cave[yval][xval-5].fval = 8;
  471.       cave[yval][xval+5].fval = 8;
  472.       switch(randint(2))
  473.         {
  474.         case 1: place_secret_door(yval+1, xval-3); break;
  475.         case 2: place_secret_door(yval-1, xval-3); break;
  476.         }
  477.       switch(randint(2))
  478.         {
  479.         case 1: place_secret_door(yval+1, xval+3); break;
  480.         case 2: place_secret_door(yval-1, xval+3); break;
  481.         }
  482.       if (randint(3) == 1)  place_object(yval, xval-2);
  483.       if (randint(3) == 1)  place_object(yval, xval+2);
  484.       vault_monster(yval, xval-2, randint(2));
  485.       vault_monster(yval, xval+2, randint(2));
  486.     }
  487.       break;
  488.     case 4:    /* Maze inside...    */
  489.       switch(randint(4))    /* Place a door    */
  490.     {
  491.     case 1:    place_secret_door(y_height-1, xval); break;
  492.     case 2:    place_secret_door(y_depth+1, xval); break;
  493.     case 3:    place_secret_door(yval, x_left-1); break;
  494.     case 4:    place_secret_door(yval, x_right+1); break;
  495.     }
  496.       for (i = y_height; i <= y_depth; i++)
  497.     for (j = x_left; j <= x_right; j++)
  498.       if (0x1 & (j+i))
  499.         cave[i][j].fval = 8;
  500.       /* Monsters just love mazes...        */
  501.       vault_monster(yval, xval-5, randint(3));
  502.       vault_monster(yval, xval+5, randint(3));
  503.       /* Traps make them entertaining...    */
  504.       vault_trap(yval, xval-3, 2, 8, randint(3));
  505.       vault_trap(yval, xval+3, 2, 8, randint(3));
  506.       /* Mazes should have some treasure too..    */
  507.       for (i = 0; i < 3; i++)
  508.     random_object(yval, xval, 1);
  509.       break;
  510.     case 5:    /* Four small rooms...    */
  511.       for (i = y_height; i <= y_depth; i++)
  512.     cave[i][xval].fval = 8;
  513.       for (i = x_left; i <= x_right; i++)
  514.     cave[yval][i].fval = 8;
  515.       switch(randint(2))
  516.     {
  517.     case 1:
  518.       i = randint(10);
  519.       place_secret_door(y_height-1, xval-i);
  520.       place_secret_door(y_height-1, xval+i);
  521.       place_secret_door(y_depth+1, xval-i);
  522.       place_secret_door(y_depth+1, xval+i);
  523.       break;
  524.     case 2:
  525.       i = randint(3);
  526.       place_secret_door(yval+i, x_left-1);
  527.       place_secret_door(yval-i, x_left-1);
  528.       place_secret_door(yval+i, x_right+1);
  529.       place_secret_door(yval-i, x_right+1);
  530.       break;
  531.     }
  532.       /* Treasure in each one...        */
  533.       random_object(yval, xval, 2+randint(2));
  534.       /* Gotta have some monsters...        */
  535.       vault_monster(yval+2, xval-4, randint(2));
  536.       vault_monster(yval+2, xval+4, randint(2));
  537.       vault_monster(yval-2, xval-4, randint(2));
  538.       vault_monster(yval-2, xval+4, randint(2));
  539.       break;
  540.     }
  541. }
  542.  
  543.  
  544. /* Builds a room at a row, column coordinate        -RAK-    */
  545. /* Type 3 unusual rooms are cross shaped                */
  546. build_type3(yval, xval)
  547. int yval, xval;
  548. {
  549.   int y_height, y_depth;
  550.   int x_left, x_right;
  551.   register int i0, i, j;
  552.   floor_type cur_floor;
  553.   register cave_type *c_ptr;
  554.  
  555.   if (dun_level <= randint(25))
  556.     cur_floor = lopen_floor;    /* Floor with light    */
  557.   else
  558.     cur_floor = dopen_floor;    /* Dark floor        */
  559.   i0 = 2 + randint(2);
  560.   y_height = yval - i0;
  561.   y_depth  = yval + i0;
  562.   x_left   = xval - 1;
  563.   x_right  = xval + 1;
  564.   for (i = y_height; i <= y_depth; i++)
  565.     for (j = x_left; j <= x_right; j++)
  566.       {
  567.     cave[i][j].fval  = cur_floor.ftval;
  568.     cave[i][j].fopen = cur_floor.ftopen;
  569.       }
  570.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  571.     {
  572.       c_ptr = &cave[i][x_left-1];
  573.       c_ptr->fval  = rock_wall1.ftval;
  574.       c_ptr->fopen = rock_wall1.ftopen;
  575.       c_ptr = &cave[i][x_right+1];
  576.       c_ptr->fval  = rock_wall1.ftval;
  577.       c_ptr->fopen = rock_wall1.ftopen;
  578.     }
  579.   for (i = x_left; i <= x_right; i++)
  580.     {
  581.       c_ptr = &cave[y_height-1][i];
  582.       c_ptr->fval  = rock_wall1.ftval;
  583.       c_ptr->fopen = rock_wall1.ftopen;
  584.       c_ptr = &cave[y_depth+1][i];
  585.       c_ptr->fval  = rock_wall1.ftval;
  586.       c_ptr->fopen = rock_wall1.ftopen;
  587.     }
  588.   i0 = 2 + randint(9);
  589.   y_height = yval - 1;
  590.   y_depth  = yval + 1;
  591.   x_left   = xval - i0;
  592.   x_right  = xval + i0;
  593.   for (i = y_height; i <= y_depth; i++)
  594.     for (j = x_left; j <= x_right; j++)
  595.       {
  596.     cave[i][j].fval  = cur_floor.ftval;
  597.     cave[i][j].fopen = cur_floor.ftopen;
  598.       }
  599.   for (i = (y_height - 1); i <= (y_depth + 1); i++)
  600.     {
  601.       c_ptr = &cave[i][x_left-1];
  602.       if (c_ptr->fval != cur_floor.ftval)
  603.     {
  604.       c_ptr->fval  = rock_wall1.ftval;
  605.       c_ptr->fopen = rock_wall1.ftopen;
  606.     }
  607.       c_ptr = &cave[i][x_right+1];
  608.       if (c_ptr->fval != cur_floor.ftval)
  609.     {
  610.       c_ptr->fval  = rock_wall1.ftval;
  611.       c_ptr->fopen = rock_wall1.ftopen;
  612.     }
  613.     }
  614.   for (i = x_left; i <= x_right; i++)
  615.     {
  616.       c_ptr = &cave[y_height-1][i];
  617.       if (c_ptr->fval != cur_floor.ftval)
  618.     {
  619.       c_ptr->fval  = rock_wall1.ftval;
  620.       c_ptr->fopen = rock_wall1.ftopen;
  621.     }
  622.       c_ptr = &cave[y_depth+1][i];
  623.       if (c_ptr->fval != cur_floor.ftval)
  624.     {
  625.       c_ptr->fval  = rock_wall1.ftval;
  626.       c_ptr->fopen = rock_wall1.ftopen;
  627.     }
  628.     }
  629.   /* Special features...            */
  630.   switch(randint(4))
  631.     {
  632.     case 1:    /* Large middle pillar        */
  633.       for (i = yval-1; i <= yval+1; i++)
  634.     for (j = xval-1; j <= xval+1; j++)
  635.       cave[i][j].fval = 8;
  636.       break;
  637.     case 2:    /* Inner treasure vault        */
  638.       for (i = yval-1; i <= yval+1; i++)
  639.     {
  640.       cave[i][xval-1].fval   = 8;
  641.       cave[i][xval+1].fval   = 8;
  642.     }
  643.       cave[yval-1][xval].fval  = 8;
  644.       cave[yval+1][xval].fval  = 8;
  645.       switch(randint(4))    /* Place a door    */
  646.     {
  647.     case 1:    place_secret_door(yval-1, xval); break;
  648.     case 2:    place_secret_door(yval+1, xval); break;
  649.     case 3:    place_secret_door(yval, xval-1); break;
  650.     case 4:    place_secret_door(yval, xval+1); break;
  651.     }
  652.       /* Place a treasure in the vault        */
  653.       place_object(yval, xval);
  654.       /* Let's guard the treasure well...    */
  655.       vault_monster(yval, xval, 2+randint(2));
  656.       /* Traps naturally            */
  657.       vault_trap(yval, xval, 4, 4, 1+randint(3));
  658.       break;
  659.     case 3:
  660.       if (randint(3) == 1)
  661.     {
  662.       cave[yval-1][xval-2].fval = 8;
  663.       cave[yval+1][xval-2].fval = 8;
  664.       cave[yval-1][xval+2].fval = 8;
  665.       cave[yval-1][xval+2].fval = 8;
  666.       cave[yval-2][xval-1].fval = 8;
  667.       cave[yval-2][xval+1].fval = 8;
  668.       cave[yval+2][xval-1].fval = 8;
  669.       cave[yval+2][xval+1].fval = 8;
  670.       if (randint(3) == 1)
  671.         {
  672.           place_secret_door(yval, xval-2);
  673.           place_secret_door(yval, xval+2);
  674.           place_secret_door(yval-2, xval);
  675.           place_secret_door(yval+2, xval);
  676.         }
  677.     }
  678.       else if (randint(3) == 1)
  679.     {
  680.       cave[yval][xval].fval = 8;
  681.       cave[yval-1][xval].fval = 8;
  682.       cave[yval+1][xval].fval = 8;
  683.       cave[yval][xval-1].fval = 8;
  684.       cave[yval][xval+1].fval = 8;
  685.     }
  686.       else if (randint(3) == 1)
  687.     cave[yval][xval].fval = 8;
  688.       break;
  689.     case 4:
  690.       break;
  691.     }
  692. }
  693.  
  694.  
  695. /* Constructs a tunnel between two points        */
  696. build_tunnel(row1, col1, row2, col2)
  697. int row1, col1, row2, col2;
  698. {
  699.   register int tmp_row, tmp_col;
  700.   int row_dir, col_dir;
  701.   register int i, j;
  702.   coords tunstk[1000];
  703.   coords wallstk[1000];
  704.   int tunptr;
  705.   int wallptr;
  706.   int stop_flag, door_flag;
  707.   cave_type *c_ptr, *d_ptr;
  708.  
  709.   /* Main procedure for Tunnel            */
  710.   /* Note: 9 is a temporary value        */
  711.   stop_flag = FALSE;
  712.   door_flag = FALSE;
  713.   tunptr    = 0;
  714.   wallptr   = 0;
  715.   correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
  716.   do
  717.     {
  718.       if (randint(100) > DUN_TUN_CHG)
  719.     rand_dir(&row_dir, &col_dir, row1, col1, row2, col2, DUN_TUN_RND);
  720.       tmp_row = row1 + row_dir;
  721.       tmp_col = col1 + col_dir;
  722.       while (!in_bounds(tmp_row, tmp_col))
  723.     {
  724.       rand_dir(&row_dir, &col_dir, row1, col1, row2, col2, DUN_TUN_RND);
  725.       tmp_row = row1 + row_dir;
  726.       tmp_col = col1 + col_dir;
  727.     }
  728.       c_ptr = &cave[tmp_row][tmp_col];
  729.       if (c_ptr->fval == rock_wall1.ftval)
  730.     {
  731.       row1 = tmp_row;
  732.       col1 = tmp_col;
  733.       wallstk[wallptr].y = row1;
  734.       wallstk[wallptr].x = col1;
  735.       if (wallptr < 1000)
  736.         wallptr++;
  737.       for (i = row1-1; i <= row1+1; i++)
  738.         for (j = col1-1; j <= col1+1; j++)
  739.           if (in_bounds(i, j))
  740.         {
  741.           d_ptr = &cave[i][j];
  742.           if ((d_ptr->fval >= 10) && (d_ptr->fval <= 12))
  743.             d_ptr->fval = 9;
  744.         }
  745.     }
  746.       else if (c_ptr->fval == corr_floor1.ftval)
  747.     {
  748.       row1 = tmp_row;
  749.       col1 = tmp_col;
  750.       if (!door_flag)
  751.         {
  752.           if (doorptr < 100)
  753.         {
  754.           doorstk[doorptr].y = row1;
  755.           doorstk[doorptr].x = col1;
  756.           doorptr++;
  757.         }
  758.           door_flag = TRUE;
  759.         }
  760.       if (randint(100) > DUN_TUN_CON)
  761.         stop_flag = TRUE;
  762.     }
  763.       else if (c_ptr->fval == 0)
  764.     {
  765.       row1 = tmp_row;
  766.       col1 = tmp_col;
  767.       tunstk[tunptr].y = row1;
  768.       tunstk[tunptr].x = col1;
  769.       if (tunptr < 1000)
  770.         tunptr++;
  771.       door_flag = FALSE;
  772.     }
  773.       else if (c_ptr->fval != 9)
  774.     {
  775.       row1 = tmp_row;
  776.       col1 = tmp_col;
  777.     }
  778.     }
  779.   while (((row1 != row2) || (col1 != col2)) && (!stop_flag));
  780.   for (i = 0; i < tunptr; i++)
  781.     {
  782.       cave[tunstk[i].y][tunstk[i].x].fval  = corr_floor1.ftval;
  783.       cave[tunstk[i].y][tunstk[i].x].fopen = corr_floor1.ftopen;
  784.     }
  785.   for (i = 0; i < wallptr; i++)
  786.     {
  787.       c_ptr = &cave[wallstk[i].y][wallstk[i].x];
  788.       if (c_ptr->fval == 9)
  789.     {
  790.       if (randint(100) < DUN_TUN_PEN)
  791.         place_door(wallstk[i].y, wallstk[i].x);
  792.       else
  793.         {
  794.           c_ptr->fval  = corr_floor2.ftval;
  795.           c_ptr->fopen = corr_floor2.ftopen;
  796.         }
  797.     }
  798.     }
  799. }
  800.  
  801.  
  802. int next_to(y, x)
  803. register int y, x;
  804. {
  805.   int next;
  806.  
  807.   if (next_to8(y, x, 4, 5, 6) > 2)
  808.     if (((cave[y-1][x].fval >= 10) && (cave[y-1][x].fval <= 12)) &&
  809.     ((cave[y+1][x].fval >= 10) && (cave[y+1][x].fval <= 12)))
  810.       next = TRUE;
  811.     else if (((cave[y][x-1].fval >= 10) && (cave[y][x-1].fval <= 12)) &&
  812.          ((cave[y][x+1].fval >= 10) && (cave[y][x+1].fval <= 12)))
  813.       next = TRUE;
  814.     else
  815.       next = FALSE;
  816.   else
  817.     next = FALSE;
  818.   return(next);
  819. }
  820.  
  821. /* Places door at y, x position if at least 2 walls found    */
  822. try_door(y, x)
  823. register int y, x;
  824. {
  825.   if (randint(100) > DUN_TUN_JCT)
  826.     if (cave[y][x].fval == corr_floor1.ftval)
  827.       if (next_to(y, x))
  828.     place_door(y, x);
  829. }
  830.  
  831.  
  832. /* Cave logic flow for generation of new dungeon        */
  833. cave_gen()
  834. {
  835.   struct spot_type
  836.     {
  837.       int endx;
  838.       int endy;
  839.     };
  840.   int room_map[20][20];
  841.   register int i, j, k;
  842.   int y1, x1, y2, x2;
  843.   int pick1, pick2;
  844.   int row_rooms, col_rooms;
  845.   int alloc_level;
  846.   worlint yloc[400];
  847.   worlint xloc[400];
  848.  
  849.   int set_1_2();
  850.   int set_1_2_4();
  851.   int set_4();
  852.  
  853.   row_rooms = 2*(cur_height/SCREEN_HEIGHT);
  854.   col_rooms = 2*(cur_width /SCREEN_WIDTH);
  855.   for (i = 0; i < row_rooms; i++)
  856.     for (j = 0; j < col_rooms; j++)
  857.       room_map[i][j] = FALSE;
  858.   for (i = 0; i < randnor(DUN_ROO_MEA, 2); i++)
  859.     room_map[randint(row_rooms)-1][randint(col_rooms)-1] = TRUE;
  860.   k = 0;
  861.   for (i = 0; i < row_rooms; i++)
  862.     for (j = 0; j < col_rooms; j++)
  863.       if (room_map[i][j] == TRUE)
  864.     {
  865.       yloc[k] = i * (QUART_HEIGHT * 2 + 1) + QUART_HEIGHT;
  866.       xloc[k] = j * (QUART_WIDTH * 2 + 1) + QUART_WIDTH;
  867.       if (dun_level > randint(DUN_UNUSUAL))
  868.         switch(randint(3))
  869.           {
  870.           case 1: build_type1(yloc[k], xloc[k]); break;
  871.           case 2: build_type2(yloc[k], xloc[k]); break;
  872.           case 3: build_type3(yloc[k], xloc[k]); break;
  873.           }
  874.       else
  875.         build_room(yloc[k], xloc[k]);
  876.       k++;
  877.     }
  878.   for (i = 0; i < k; i++)
  879.     {
  880.       pick1 = randint(k) - 1;
  881.       pick2 = randint(k) - 1;
  882.       y1 = yloc[pick1];
  883.       x1 = xloc[pick1];
  884.       yloc[pick1] = yloc[pick2];
  885.       xloc[pick1] = xloc[pick2];
  886.       yloc[pick2] = y1;
  887.       xloc[pick2] = x1;
  888.       }
  889.   doorptr = 0;
  890.   for (i = 0; i < k-1; i++)
  891.     {
  892.       y1 = yloc[i];
  893.       x1 = xloc[i];
  894.       y2 = yloc[i+1];
  895.       x2 = xloc[i+1];
  896.       build_tunnel(y2, x2, y1, x1);
  897.       }
  898.   fill_cave(rock_wall1);
  899.   for (i = 0; i < DUN_STR_MAG; i++)
  900.     place_streamer(rock_wall2, DUN_STR_MC);
  901.   for (i = 0; i < DUN_STR_QUA; i++)
  902.     place_streamer(rock_wall3, DUN_STR_QC);
  903.   place_boundary();
  904.   /* Place intersection doors    */
  905.   for (i = 0; i < doorptr; i++)
  906.     {
  907.       try_door(doorstk[i].y, doorstk[i].x-1);
  908.       try_door(doorstk[i].y, doorstk[i].x+1);
  909.       try_door(doorstk[i].y-1, doorstk[i].x);
  910.       try_door(doorstk[i].y+1, doorstk[i].x);
  911.     }
  912.   alloc_level = (dun_level/3);
  913.   if (alloc_level < 2)
  914.     alloc_level = 2;
  915.   else if (alloc_level > 10)
  916.     alloc_level = 10;
  917.   place_stairs(2, randint(2)+2, 3);
  918.   place_stairs(1, randint(2), 3);
  919.   alloc_monster(set_1_2, (randint(8)+MIN_MALLOC_LEVEL+alloc_level), 0, TRUE);
  920.   alloc_object(set_4, 3, randint(alloc_level));
  921.   alloc_object(set_1_2, 5, randnor(TREAS_ROOM_ALLOC, 3));
  922.   alloc_object(set_1_2_4, 5, randnor(TREAS_ANY_ALLOC, 3));
  923.   alloc_object(set_1_2_4, 4, randnor(TREAS_GOLD_ALLOC, 3));
  924.   alloc_object(set_1_2_4, 1, randint(alloc_level));
  925.   if (dun_level >= WIN_MON_APPEAR)  place_win_monster();
  926. }
  927.  
  928.  
  929. /* Builds a store at a row, column coordinate            */
  930. build_store(store_num, y, x)
  931. int store_num, y, x;
  932. {
  933.   int yval, y_height, y_depth;
  934.   int xval, x_left, x_right;
  935.   register int i, j;
  936.   int cur_pos;
  937.   register cave_type *c_ptr;
  938.  
  939.   yval       = y*10 + 5;
  940.   xval     = x*16 + 16;
  941.   y_height = yval - randint(3);
  942.   y_depth  = yval + randint(4);
  943.   x_left   = xval - randint(6);
  944.   x_right  = xval + randint(6);
  945.   for (i = y_height; i <= y_depth; i++)
  946.     for (j = x_left; j <= x_right; j++)
  947.       {
  948.     cave[i][j].fval  = boundary_wall.ftval;
  949.     cave[i][j].fopen = boundary_wall.ftopen;
  950.       }
  951.   switch(randint(4))
  952.     {
  953.     case 1:
  954.       i = randint(y_depth-y_height) + y_height - 1;
  955.       j = x_left;
  956.       break;
  957.     case 2:
  958.       i = randint(y_depth-y_height) + y_height - 1;
  959.       j = x_right;
  960.       break;
  961.     case 3:
  962.       i = y_depth;
  963.       j = randint(x_right-x_left) + x_left - 1;
  964.       break;
  965.     case 4:
  966.       i = y_height;
  967.       j = randint(x_right-x_left) + x_left - 1;
  968.       break;
  969.     }
  970.   c_ptr = &cave[i][j];
  971.   c_ptr->fval  = corr_floor3.ftval;
  972.   c_ptr->fopen = corr_floor3.ftopen;
  973.   popt(&cur_pos);
  974.   c_ptr->tptr = cur_pos;
  975.   t_list[cur_pos] = store_door[store_num];
  976. }
  977.  
  978.  
  979. /* Town logic flow for generation of new town        */
  980. town_gen()
  981. {
  982.   register int i, j, k, l, m;
  983.   int rooms[6];
  984.  
  985.   int set_1_2();
  986.  
  987.   set_seed(town_state, town_seed);
  988.   for (i = 0; i < 6; i++)
  989.     rooms[i] = i;
  990.   l = 6;
  991.   for (i = 0; i < 2; i++)
  992.     for (j = 0; j < 3; j++)
  993.       {
  994.     k = randint(l) - 1;
  995.     build_store(rooms[k], i, j);
  996.     for (m = k; m < l-1; m++)
  997.       rooms[m] = rooms[m+1];
  998.     l--;
  999.       }
  1000.   fill_cave(dopen_floor);
  1001.   /* make stairs before reset_seed, so that they don't move around */
  1002.   place_stairs(2, 1, 0);
  1003.   place_boundary();
  1004.   reset_seed();
  1005.   if (0x1 & (turn / 5000))
  1006.     {        /* Night    */
  1007.       for (i = 0; i < cur_height; i++)
  1008.     for (j = 0; j < cur_width; j++)
  1009.       if (cave[i][j].fval != dopen_floor.ftval)
  1010.         cave[i][j].pl = TRUE;
  1011.       alloc_monster(set_1_2, MIN_MALLOC_TN, 3, TRUE);
  1012.     }
  1013.   else
  1014.     {        /* Day    */
  1015.       for (i = 0; i < cur_height; i++)
  1016.     for (j = 0; j < cur_width; j++)
  1017.       cave[i][j].pl = TRUE;
  1018.       alloc_monster(set_1_2, MIN_MALLOC_TD, 3, TRUE);
  1019.     }
  1020.   store_maint();
  1021. }
  1022.  
  1023.  
  1024. /* Generates a random dungeon level            -RAK-    */
  1025. generate_cave()
  1026. {
  1027.   panel_row_min    = 0;
  1028.   panel_row_max    = 0;
  1029.   panel_col_min    = 0;
  1030.   panel_col_max    = 0;
  1031.   char_row        = -1;
  1032.   char_col        = -1;
  1033.  
  1034.   tlink();
  1035.   mlink();
  1036.   blank_cave();
  1037.  
  1038.   if (dun_level == 0)
  1039.     {
  1040.       cur_height = SCREEN_HEIGHT;
  1041.       cur_width  = SCREEN_WIDTH;
  1042.       max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1043.       max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1044.       panel_row = max_panel_rows;
  1045.       panel_col = max_panel_cols;
  1046.       town_gen();
  1047.     }
  1048.   else
  1049.     {
  1050.       cur_height = MAX_HEIGHT;
  1051.       cur_width  = MAX_WIDTH;
  1052.       max_panel_rows = (cur_height/SCREEN_HEIGHT)*2 - 2;
  1053.       max_panel_cols = (cur_width /SCREEN_WIDTH )*2 - 2;
  1054.       panel_row = max_panel_rows;
  1055.       panel_col = max_panel_cols;
  1056.       cave_gen();
  1057.     }
  1058. }
  1059.  
  1060.